iT邦幫忙

2022 iThome 鐵人賽

DAY 30
2

架構與部署

本系列文章已來到了尾聲,在過程中我們學習如何建構服務功能,使用模組套件與工具,最後我們要來學習如何選擇架構以及部署微服務。

架構

部署之前,我們需要知道 Moleculer 框架可以支援哪些應用程式架構。

單體式架構

在本系列開始的時候,我們提到了我們熟悉的單體式系統,而 Moleculer 框架也支援這種架構模式。在單體式架構中,每個服務都像是單體一樣,在單一個節點上運作。不會有網路延遲問題,不需要 Transporter ,直接在本地呼叫是最快的。這種架構也可以應用在單機軟體,例如將服務直接內嵌到 WebView2[3] 架構,讓使用者可以直接離線使用。


Fig. 1. 單體式架構圖

微服務架構

當所有的服務都在單一個節點上運作,並且透過 Transporter 來進行通訊時,這就是一種典型的微服務架構。在這種架構下,網路延遲問題是肯定會發生的,但是你的服務能夠依賴容錯機制,而且可以自行擴充服務來解決此問題。


Fig. 2. 微服務架構圖

混合式架構

混合式架構結合了單體式架構與微服務架構的優勢,它會在同一個節點下運行關聯性高的服務,依循此規則來建立多個節點。例如 post 服務經常需要請求 usercomments 服務,這個時候就會將它們放在同一個節點上,如此一來就能降低服務間的網路延遲。如果 user 節點超過請求負荷,你只要透過微服務的特性來擴展它。


Fig. 3. 混合式架構圖

ServiceBroker 會優先嘗試向本地服務請求來減少網路延遲,但你也可以在配置檔中的 registry 屬性設定關閉此功能 preferLocal: false

Docekr 部署

我們已經學習了 Moleculer 框架支援的各種架構,接下來我們可以使用 moleculer-runner 與 Docker[3] 來部署多個容器,容器化的微服務能夠使系統更快的部署且方便管理。透過 moleculer-runner 的好處是它可以讀取 Docker 部署時環境變數。

以下的範例來自於 Moleculer 的 project 樣板。

Dockerfile

使用 Dockerfile 來建立 Moleculer 服務啟動腳本。

FROM node:current-alpine

ENV NODE_ENV=production

RUN mkdir /app
WORKDIR /app

COPY package.json package-lock.json ./

RUN npm install --production

COPY . .

CMD ["npm", "start"]

Docker Compose

使用 Docker compose 檔案來建立並執行 Moleculer 服務,並啟動 mongo 、 NATS 及 traefik[4] 服務。

設定所需的環境變數。

docker-compose.env

NAMESPACE=
LOGGER=true
LOGLEVEL=info
SERVICEDIR=services # 設定本地服務目錄

TRANSPORTER=nats://nats:4222 # 設定所有容器的 Transporter
MONGO_URI=mongodb://mongo/project-demo # 設定 MongoDB URI

容器配置。

docker-compose.yml

version: "3.3"

services:

  api:
    build:
      context: .
    image: project-demo
    env_file: docker-compose.env
    environment:
      SERVICES: api # 這個容器中的 Moleculer Runner 只會啟動 'api' 服務
      PORT: 3000    # API 閘道器連接埠
    depends_on:
      - nats
    labels:
      - "traefik.enable=true"
      - "traefik.http.routers.api-gw.rule=PathPrefix(`/`)"
      - "traefik.http.services.api-gw.loadbalancer.server.port=3000"
    networks:
      - internal

  greeter:
    build:
      context: .
    image: project-demo
    env_file: docker-compose.env
    environment:
      SERVICES: greeter # 這個容器中的 Moleculer Runner 只會啟動 'greeter' 服務
    depends_on:
      - nats
    networks:
      - internal

  products:
    build:
      context: .
    image: project-demo
    env_file: docker-compose.env
    environment:
      SERVICES: products # 這個容器中的 Moleculer Runner 只會啟動 'products' 服務
    depends_on:
      - mongo
      - nats
    networks:
      - internal

  mongo:
    image: mongo:4
    volumes:
      - data:/data/db
    networks:
      - internal

  nats:
    image: nats:2
    networks:
      - internal

  traefik:
    image: traefik:v2.1
    command:
      - "--api.insecure=true" # 不安全模式[5] ,請不要在生產環境使用
      - "--providers.docker=true"
      - "--providers.docker.exposedbydefault=false"
    ports:
      - 3000:80
      - 3001:8080
    volumes:
      - /var/run/docker.sock:/var/run/docker.sock:ro
    networks:
      - internal
      - default

networks:
  internal:

volumes:
  data:

啟動容器。

$ docker-compose up -d

你可以由 http://<docker-host>:3000/ 來瀏覽你的應用。也可以由 http://<docker-host>:3001/ 來進入 Traefik 儀表板。

Kubernetes 部署

Moleculer 社群仍在努力建立 Kubernetes[7] 部署的解決方案[8] ,你可以參考以下範例:

  • moleculer-deployment-thoughts, Dan Kuida[9]
  • moleculer-k8s-examples, Leandro Hoffmann[10]
  • Moleculer k8 depoyment, tobydeh[11]

如何選擇架構來部署

在開發全新的系統時,你可能會面臨單體式與微服務的抉擇,你可能會因為單體式系統容易開發而選擇它,也可能因為微服務的靈活性而計畫使用它。

Moleculer 官方手冊中建議,使用 Moleculer 的話,可以先不用擔心這個問題,只要在開發時期先以單體式架構開發,將所有的服務都放在單一節點,就能快速的測試你的程式邏輯。開發完成後,只需要將服務部署到單一節點即可。當系統逐漸長大後,你不需要修改任何程式,只需要建立一個 Transporter ,把每個服務都部署到單一節點上即可,這時候就會是微服務架構。

筆者並不完全認同此說法,微服務在程式架構規劃上較為複雜,而開發時程也相對較長,如果你不清楚業務邏輯而規劃錯誤,可能會比使用單體式架構還差。但不可否認的是 Moleculer 使用上相當容易,筆者認為非常適合新手入門,假如你的應用非常簡單,開發上也沒有太大的時程壓力,那不妨試試看這套相對容易上手的微服務框架吧。

參考文獻

[1] Clustering, https://moleculer.services/docs/0.14/clustering.html
[2] Deploying, https://moleculer.services/docs/0.14/deploying.html
[3] Microsoft Edge WebView2, https://developer.microsoft.com/en-us/microsoft-edge/webview2/
[4] Docker, https://www.docker.com/
[5] Traefik proxy, https://traefik.io/traefik/
[6] Traefik Insecure Mode, https://doc.traefik.io/traefik/operations/dashboard/#insecure-mode
[7] Kubernetes, https://kubernetes.io/
[8] Kubernetes deployment in Docs, https://github.com/moleculerjs/moleculer/issues/512
[9] step by step tutorial, Dan Kuida, https://dankuida.com/moleculer-deployment-thoughts-8e0fc8c0fb07
[10] code samples, lehno, https://github.com/lehno/moleculer-k8s-examples
[11] deployment guide, https://gist.github.com/tobydeh/0aa33a5b672821f777165159b6a22cc5

家家酒小劇場

  • Otter - 今天是最後一天了,真的捨不得結束啦QAQ
  • Boxy - 曲終人散,總是要結束這門課,有緣的話下個系列再見囉,掰掰 ^Q^
  • Otter - 掰掰QAQ

上一篇
Day 29 : 測試
下一篇
Day 31 : 後記
系列文
Moleculer 家家酒31
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

2 則留言

1
雷N
iT邦研究生 1 級 ‧ 2022-09-30 09:09:52

E04團隊第二位成員完賽 %%%%%
Moleculer這框架真的很多微服務相關的組件都封裝好了 讚讚

0
json_liang
iT邦研究生 5 級 ‧ 2022-09-30 10:51:21

Moleculer這框架真強大

感謝大大分享這個工具

我要留言

立即登入留言